var fs=require('fs');

function safe(t) {
	if (t==undefined) return "--undefined--";
	if (t==null) return "--null--";
	return t.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}

/*****************************************************************************/
OneWorldCmsViews=function() {
	this.paths=['views/'];
	this.cachepaths=['views/'];
//	this.jazz=require('jazz');
	this.compile=require('./viewcompiler').compile;
	this.compiled={};
	return this;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.setPaths=function(arr,arrc) {
	this.paths=arr;
	this.cachepaths=arrc;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.setGlobalspace=function(space)
{
	this.globalspace=space;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.compileFile=function(tmplname)
{
	var i=0;
	var tmpl;
	while (i<this.paths.length && !tmpl) {
		var path=this.paths[i]+tmplname+".html";
		if (this.compiled[path]) {
			tmpl=this.compiled[path];
		} else {
			try {
				var f=new fs.File(path);
				f.open('r');
				var contents=f.read();
				f.close();
				var data;
				try {
					data=contents.toString("utf-8");
				} catch (e2) {
					return "<b>Can not load file "+path+" - not utf-8?</b>";
				}
				try {
					this.compiled[path]=tmpl=this.compile(data,this.cachepaths[i],tmplname);
				} catch(e1) {
					return "<pre class='error'>Template: "+tmplname+"\n<h1>Error thrown by compiler: "+e1+"</h1>"+safe(this.globalspace.Dumper(e1))+"</pre><h1>Template:</h1><pre>"+safe(data)+"</pre>";
				}
			} catch (e) {
				i++;
				continue;
			}
		}
	}
//	throw new Error(tmpl);
	return tmpl;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.process=function(tmplname,space)
{
	if (!space) space=this.globalspace;
	var tmpl=this.compileFile(tmplname);
	if (!tmpl) return "<b>[No template "+tmplname+"]</b>";
	if (typeof tmpl != "function") return "<b>[Compilation error "+tmplname+"]</b><br/>"+tmpl;
	var ret;
	try {
		ret=tmpl(this.globalspace,space);
	} catch(e2) {
		return "<pre class='error'>Template: "+tmplname+"\n<h1>Error thrown by exec: "+e2+"</h1><pre>"+safe(this.globalspace.Dumper(e2))+"</pre>";
	}
	return ret;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.apply=function(tmplcode,space)
{
	var ret;
	try {
		var tmpl;
		var path=this.paths[0]+'---'+tmplcode;
		if (this.compiled[path]) {
			tmpl=this.compiled[path];
		} else {
			this.compiled[path]=tmpl=this.compile(tmplcode);
		}
		ret=tmpl(this.globalspace,space);
	} catch(e) {
		return "<pre class='error'>Template: "+tmplcode+"\nError: "+this.globalspace.Dumper(e)+"</pre>";
	}
	return ret;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.clientSide=function(space,folder)
{
	var fh=this.recurseGetFolders(folder);
	var f=new fs.File(space.functions.uploads_folder(space,1)+"views-"+folder+".js");
/*	if (f.exists() && f.stat()[9]>fh.date) {
		f.open("r");
		var ret=f.read().toString("utf-8");
		f.close();
		space.page.responseHeaders["Content-type"]="text/javascript";
		return ret;
	}*/
	var fh2=this.buildClientSide(space,fh);
	var ret="";
//	ret+="/* Tree:\n"+fh.folders.join("\n")+"\n*/\n";
	
	ret+="/* Errors compiling view templates:\n";
	for (var fname in fh2.errors) {
		ret+="	TEMPLATE "+fname+":\n";
		ret+="		"+fh2.errors[fname].replace(/\n/g,"\n\t\t");
	}
	ret+="*/\n";
	ret+="/* Cached view templates list:\n";
	for (var fname in fh2.files) {
		ret+="	"+fname+"\n";
	}
	ret+="*/\n";
	for (var fname in fh2.files) {
		a=fh2.files[fname].replace(/^data=/,"");
		ret+="views.c['"+fname+"']="+a+";\n";
	}
	try {
		f.open("w");
		f.write(ret);
		f.close();
	} catch (e) {
		throw new Error("Can not save file "+f.toString()+" - "+e);
	}
	space.page.responseHeaders["Content-type"]="text/javascript";
	return ret;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.buildClientSide=function(space,fh)
{
	var r={files:{},errors:{}};
	for (var i=0,s=fh.folders.length;i<s;i++) {
		var files={};
		for (var i2=0,s2=this.paths.length;i2<s2;i2++) {
			var d=new fs.Directory(this.paths[i2]+fh.folders[i]);
			if (!d.exists()) continue;
			d.listFiles().forEach(function(x) {var a=x.match(/^(.*)\.html$/);if (!a) return;files[a[1]]=1;});
		}
		for (var fil in files) {
			var file=(fh.folders[i]+"/"+fil).replace(/\/{2,}/g,"/");
			try {
				r.files[file]=this.buildClientSideFile(file);
			} catch (e) {
				r.errors[file]=e.toString();
			}
		}
	}
	return r;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.buildClientSideFile=function(tmplname)
{
	var i=0;
	var tmpl;
	var f;
	while (!f) {//i<this.paths.length && !tmpl) {
		var path=this.paths[i]+tmplname+".html";
		f=new fs.File(path);
		if (!f.exists()) {
			i++;
			f=undefined;
		}
	}
	if (!f) throw new Error("File not found - "+filename);
	f.open('r');
	var contents=f.read();
	f.close();
	var data=contents.toString("utf-8");
	tmpl=this.compile(data,this.cachepaths[i],tmplname,1);
	return tmpl;
}

/*****************************************************************************/
OneWorldCmsViews.prototype.recurseGetFolders=function(folder,r)
{
	if (!r) r={date:undefined,folders:[]};
	var subdirs;
	for (var i=0,s=this.paths.length;i<s;i++) {
		var d=new fs.Directory(this.paths[i]+folder);
		if (!d.exists()) continue;
		var motime=d.stat()[9];
		if (r.date==undefined || motime>r.date) r.date=motime;
		if (!subdirs) subdirs={};
		d.listDirectories().forEach(function(x) { subdirs[x]=1;});
	}
	if (subdirs) {
		r.folders.push(folder);
		for (var k in subdirs) {
			this.recurseGetFolders(folder+"/"+k,r);
		}
	}
	return r;
}

/*****************************************************************************/


/*****************************************************************************/
exports.create=function() {
	return new OneWorldCmsViews();
}

/*****************************************************************************/
